package cn.ilikes.tools.nosql.jpa.clients.indexs;

import org.slf4j.Logger;

import cn.ilikes.tools.logs.Loggerfactory;
import cn.ilikes.tools.nosql.jpa.JPASQLPersistenUnitEnv;
import cn.ilikes.tools.nosql.jpa.clients.indexs.IClientIndex.IndexType;
import cn.ilikes.tools.nosql.jpa.clients.indexs.index.ABIndexSource;
import cn.ilikes.tools.nosql.jpa.configs.indexs.IndexConfigs;

public abstract class ABClientIndexerFactory implements IClientIndexerFactory {
	private static Logger logger = Loggerfactory.instance(ABClientIndexerFactory.class);

	private JPASQLPersistenUnitEnv persistenUnitEnv;

	private ABIndexSource indexSource;

	private boolean init = false;

	protected ABClientIndexerFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		super();
		this.persistenUnitEnv = persistenUnitEnv;
		init();
	}

	public JPASQLPersistenUnitEnv getPersistenUnitEnv() {
		return persistenUnitEnv;
	}

	@Override
	public void init() {
		if (init)
			return;
		Loggerfactory.info(logger, "Start Init  Client Indexer Factory ");
		JPASQLPersistenUnitEnv persistenUnitEnv = getPersistenUnitEnv();
		IndexConfigs indexConfigs = persistenUnitEnv.getPersistenceUnitMetadata().getIndexConfigs();
		IndexType indexType = IClientIndex.IndexType.valueOf(indexConfigs.getType());
		indexConfigs.setIndexType(indexType);
		initIndexSource(indexConfigs);
		initClientIndex(this.indexSource);
		init = true;

	}

	private void initIndexSource(IndexConfigs indexConfigs) {
		Loggerfactory.info(logger, "Init Index Source");
		ABIndexSource indexSource = createIndexSource(indexConfigs);
		indexSource.init();
		setIndexSource(indexSource);
	}

	private synchronized void initClientIndex(ABIndexSource indexSource) {
		Loggerfactory.info(logger, "Init Client Index");
		try {
			ABClientIndex clientIndex = createClientIndex(indexSource);
			clientIndex.init();

		} catch (ClientIndexingException e) {

			e.printStackTrace();
		}
		;
	}

	@Override
	public void close() {
		Loggerfactory.info(logger, "Start Close Client  Indexer Factory ! ");
		subClose();

		indexSource.close();
	}

	public abstract void subClose();

	@Override
	public boolean isOpen() {
		return indexSource.isOpen();
	}

	@Override
	public void open() {
		Loggerfactory.info(logger, "Start  open Client Indexer Factory ! ");
		indexSource.open();
		Loggerfactory.info(logger, "open Client Indexer Factory  success ! ");

	}

	protected abstract ABIndexSource createIndexSource(IndexConfigs indexConfigs);

	private void setIndexSource(ABIndexSource indexSource) {
		this.indexSource = indexSource;
	}

	protected ABIndexSource getIndexSource() {
		return indexSource;
	}

	@Override
	public ABClientIndex createClientIndex() throws ClientIndexingException {

		ABClientIndex clientIndex = createClientIndex(indexSource);
	
		return clientIndex;
	}

	protected abstract ABClientIndex createClientIndex(ABIndexSource indexSource) throws ClientIndexingException;

}
